<?php
/**
 * Created by PhpStorm.
 * User: mayn
 * Date: 2019/10/22
 * Time: 21:16
 */

//日志记录
interface  log
{
    public function write();
}
//订单记录
class OrderLog implements log{
    public function write()
    {
        // TODO: Implement write() method.
        echo 'OrderLog log write';
    }
}
//商品记录
class GoodsLog implements log{
    public function write()
    {
        // TODO: Implement write() method.
        echo 'GoodsLog log write';
    }
}
class Ioc
{
    public $binding = [];

    public function bind($abstract, $concrete) {
        //绑定的闭包
        $this->binding[$abstract]['concrete'] =  function ($ioc) use ($concrete) {
            //对象一传入 就执行方法
            return $ioc->build($concrete);
        };
    }

    public function make($abstract)
    {
        $concrete = $this->binding[$abstract]['concrete'];
        //调用闭包方法,function($this) use ($concrete){$this->build('User')}
        return $concrete($this);
    }
    //创建对象
    public function build($concrete)
    {
        $reflector = new ReflectionClass($concrete);    //User
        //获取构造函数
        $constructor = $reflector->getConstructor();
        if (is_null($constructor)) {
            //如果没有构造函数,实例化对象
            return $reflector->newInstance();
        }else {
            //获取构造函数的参数
            $dependen = $constructor->getParameters();      //log
            $intances = $this->getDependencies($dependen);
            return $reflector->newInstanceArgs($intances);
        }

    }

    protected function getDependencies($dependen) {
        $dependencies = [];
        foreach ($dependen as $paramter){
            //由于先绑定的是log,所以这里得用$this->make('log'),即最原始的类名是log,而class规范首字母大写,因此需要再加个interface(log)
            $dependencies[] = $this->make($paramter->getClass()->name);

        }
        return $dependencies;
    }
}
$ioc = new Ioc();
$ioc->bind('log','OrderLog');
$ioc->bind('user','User');

$user = $ioc->make('user');
$user->login();